#include "sub_server_mgr.h"

#include <common/base/config_mgr.h>
#include <common/base/cmd_module.h>
#include <common/base/cmd_module_mgr.h>
#include <common/base/module_mgr.h>
#include <common/base/server_mgr.h>
#include <common/log/log.h>
#include <common/net/cmd_session.h>
#include <common/net/session.h>
#include <common/net/session_mgr.h>

#include <protocols/protos/common.pb.h>
using namespace proto::common;

#include "base/db_mgr.h"
#include "base/player_mgr.h"
#include "modules/common/common_module.h"
#include "modules/common/db_module.h"
#include "modules/login/login_module.h"
#include "net/custom_data.h"

SubServerMgr::SubServerMgr() : ISubServerMgr(ServerType::eGameServer)
{
}

/**
 * @desc 全局单例实现，通过它拿到其他所有资源
 * @auth Qiwei.Gu
 * @date 2015-03-21 12:23:48
 */
bool SubServerMgr::addSubMgr(SubManagerType type, std::shared_ptr<IManager> mgr)
{
    if (!mgr)
    {
        LOG_ERROR("Add null Manager not allowed.");
        return false;
    }
    subMgrs_[type] = mgr;
    if (!mgr->init())
    {
        LOG_ERROR("Init Manager failed.");
        return false;
    }

    LOG_DEBUG("Add sub manager suc, type: " << uint32_t(type));
    return true;
}

std::shared_ptr<IManager> SubServerMgr::getSubMgr(SubManagerType type)
{
    auto it = subMgrs_.find(type);
    return it == subMgrs_.end() ? std::shared_ptr<IManager>() : it->second;
}

bool SubServerMgr::init()
{
    if (!initSessionFilter())
    {
        LOG_ERROR("Init session filter failed.");
        return false;
    }

    if (!initSubMgr())
    {
        LOG_ERROR("Init sub manager  failed.");
        return false;
    }

    if (!initConfig())
    {
        LOG_ERROR("Init conifg failed.");
        return false;
    }

    if (!initModule())
    {
        LOG_ERROR("Init sub module manager failed.");
        return false;
    }

    if (!initCmdModule())
    {
        LOG_ERROR("Init sub cmd module manager failed.");
        return false;
    }

    // dbConn_ = std::make_shared<DbConnection>();
    // if (!dbConn_->init())
    // {
    //     LOG_ERROR("DB connection init failed.");
    //     return false;
    // }
    LOG_INFO("Init sub session manager suc");
    return true;
}

bool SubServerMgr::initSessionFilter()
{
    auto sessionMgr = ServerMgr::get().getMgr<SessionMgr>(ManagerType::eSession);
    if (!sessionMgr)
    {
        LOG_ERROR("Session Manager not found, when init session filter.");
        return false;
    }
    // sessionMgr->addFilter(std::make_shared<DbSessionFilter>());
    return true;
}

/**
 * @desc 初始化管理器
 * @auth Qiwei.Gu
 * @date 2015-04-15 17:19:12
 */
bool SubServerMgr::initSubMgr()
{
    if (!addSubMgr(eDB, std::make_shared<DBMgr>()))
    {
        LOG_ERROR("Add db manger failed.");
        return false;
    }
    if (!addSubMgr(ePlayer, std::make_shared<PlayerMgr>()))
    {
        LOG_ERROR("Add Player manger failed.");
        return false;
    }
    return true;
}


/**
 * @desc 初始化配置
 * @auth Qiwei.Gu
 * @date 2015-04-15 15:14:10
 */
bool SubServerMgr::initConfig()
{
    auto cfgMgr = ServerMgr::get().getMgr<ConfigMgr>(ManagerType::eConfig);
    if (!cfgMgr)
    {
        LOG_ERROR("Config manager not inited.");
        return false;
    }
    return true;
}


/**
 * @desc 功能模块初始化
 * @auth Qiwei.Gu
 * @date 2015-04-05 22:04:58
 */
bool SubServerMgr::initModule()
{
    auto moduleMgr = ServerMgr::get().getMgr<ModuleMgr>(ManagerType::eModule);
    if (!moduleMgr)
    {
        LOG_ERROR("Module manager not inited.");
        return false;
    }
    if (!moduleMgr->addModule(proto::common::eDb, std::make_shared<DbModule>()))
    {
        LOG_ERROR("Module manager add db module failed.");
        return false;
    }
    if (!moduleMgr->addModule(proto::common::eCommon, std::make_shared<CommonModule>()))
    {
        LOG_ERROR("Module manager add common module failed.");
        return false;
    }
    if (!moduleMgr->addModule(proto::common::eLogin, std::make_shared<LoginModule>()))
    {
        LOG_ERROR("Module manager add login module failed.");
        return false;
    }
    LOG_INFO("Init sub module manager suc");
    return true;
}

/**
 * @desc 命令模块出现化
 * @auth Qiwei.Gu
 * @date 2015-04-05 22:05:42
 */
bool SubServerMgr::initCmdModule()
{
    auto cmdModuleMgr = ServerMgr::get().getMgr<CmdModuleMgr>(ManagerType::eCmdModule);
    if (!cmdModuleMgr)
    {
        LOG_ERROR("Cmd Module manager not inited.");
        return false;
    }
    return true;
}
